# Copyright (c) 2008 POTI, Inc.
#
# Permission is hereby granted, free of charge, to any person
# obtaining a copy of this software and associated documentation
# files (the "Software"), to deal in the Software without
# restriction, including without limitation the rights to use,
# copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the
# Software is furnished to do so, subject to the following
# conditions:
#
# The above copyright notice and this permission notice shall be
# included in all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
# OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
# HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
# OTHER DEALINGS IN THE SOFTWARE.

require 'rubygems'
require 'active_record'

module Wordpress
  # Replace this with your table prefix
  TABLE_PREFIX = $config['wordpress_database']['table_prefix']
  FILE_HOST = $config['wordpress_database']['file_host']
  BLOG_HOST = $config['wordpress_database']['blog_host']
  FEED_HOST = $config['wordpress_database']['feed_host']
  
  class WordpressDatabase < ActiveRecord::Base
    self.abstract_class = true
    establish_connection $config['wordpress_database']
    logger = Logger.new(File.open('wordpress.database.log', 'a'))
    
    def to_s
      attributes.each {|name, value|
        puts "#{name}: #{value}"
      }
    end  
  end
  
  class Link < WordpressDatabase
    set_primary_key 'link_id'
    set_table_name Wordpress::TABLE_PREFIX + 'links'
  end
  
  class User < WordpressDatabase
    set_primary_key 'ID'
    set_table_name Wordpress::TABLE_PREFIX + 'users'
    
    has_many :posts, :class_name => 'Wordpress::Post', :foreign_key => 'post_author', :dependent => :destroy
    has_many :metas, :class_name => 'Wordpress::UserMeta', :foreign_key => 'user_id', :dependent => :destroy
    
    def self.create_admin_from_email(email)
      name = email.split('@')[0]
      self.create_admin(
        :user_login => name,
        :user_pass => '4cb9c8a8048fd02294477fcb1a41191a', # changeme
        :user_nicename => name,
        :user_email => email,
        :user_registered => Time.now,
        :display_name => name
      )
    end
    
    def self.create_admin(*opts)
      user = create(*opts)
      user.promote_to_administrator
      user
    end

    def self.create_editor_from_email(email)
      name = email.split('@')[0]
      self.create_editor(
        :user_login => name,
        :user_pass => '4cb9c8a8048fd02294477fcb1a41191a', # changeme
        :user_nicename => name,
        :user_email => email,
        :user_registered => Time.now,
        :display_name => name
      )
    end
    
    def self.create_editor(*opts)
      user = create(*opts)
      user.promote_to_editor
      user
    end
    
    def self.create_author_from_email(email)
      name = email.split('@')[0]
      self.create_author(
        :user_login => name,
        :user_pass => '4cb9c8a8048fd02294477fcb1a41191a', # changeme
        :user_nicename => name,
        :user_email => email,
        :user_registered => Time.now,
        :display_name => name
      )
    end
    
    def self.create_author(*opts)
      user = create(*opts)
      user.promote_to_author
      user
    end
    
    def self.create_from_drupal(drupal_user)
      self.create_editor(
      :user_login => drupal_user.name,
      :user_pass => drupal_user.pass,
      :user_nicename => drupal_user.name,
      :user_email => drupal_user.mail,
      :user_registered => Time.at(drupal_user.created),
      :display_name => drupal_user.name
      )
    end
    
    def promote_to_administrator
      self.metas.clear      
      self.metas << Wordpress::UserMeta.create_capabilities_administrator
      self.metas << Wordpress::UserMeta.create_user_level(10)
    end
    
    def promote_to_editor
      self.metas.clear      
      self.metas << Wordpress::UserMeta.create_capabilities_editor
      self.metas << Wordpress::UserMeta.create_user_level(7)
    end
    
    def promote_to_subscriber
      self.metas.clear      
      self.metas << Wordpress::UserMeta.create_capabilities_subscriber
    end
    
    def promote_to_author
      self.metas.clear
      self.metas << Wordpress::UserMeta.create_capabilities_author
      self.metas << Wordpress::UserMeta.create_user_level(2)
    end
  end
  
  class UserMeta < WordpressDatabase
    set_primary_key 'umeta_id'
    set_table_name Wordpress::TABLE_PREFIX + 'usermeta'
    belongs_to :user, :class_name => 'Wordpress::User', :foreign_key => 'user_id'
    
    def self.create_capabilities_administrator
      create(
        :meta_key => Wordpress::TABLE_PREFIX+'capabilities',
        :meta_value => 'a:1:{s:13:"administrator";b:1;}'
      )
    end

    def self.create_capabilities_editor
      create(
        :meta_key => Wordpress::TABLE_PREFIX+'capabilities',
        :meta_value => 'a:1:{s:6:"editor";b:1;}'
      )
    end

    def self.create_capabilities_subscriber
      create(
        :meta_key => Wordpress::TABLE_PREFIX+'capabilities',
        :meta_value => 'a:1:{s:10:"subscriber";b:1;}'
      )
    end
    
    def self.create_capabilities_author
      create(
        :meta_key => Wordpress::TABLE_PREFIX+'capabilities',
        :meta_value => 'a:1:{s:6:"author";b:1;}'
      )
    end
    
    def self.create_user_level(level)
      create(
        :meta_key =>Wordpress::TABLE_PREFIX+'user_level',
        :meta_value => level
      )      
    end
  end
      
  class TermTaxonomy < WordpressDatabase
    set_primary_key 'term_taxonomy_id'
    set_table_name Wordpress::TABLE_PREFIX + 'term_taxonomy'
    belongs_to :term, :class_name => 'Wordpress::Term', :foreign_key => 'term_id'
  end

  class Term < WordpressDatabase
    set_primary_key 'term_id'
    set_table_name Wordpress::TABLE_PREFIX + 'terms'
    has_one :taxonomy, :class_name => 'Wordpress::TermTaxonomy', :foreign_key => 'term_id', :dependent => :destroy
    
    def self.create_category(category_name)
      term = create(
        :name => category_name,
        :slug => category_name.downcase.gsub("\s", '-').gsub(/[^\w\d\-]/, '')
      )
      term.create_taxonomy(
        :taxonomy => 'category',
        :count => 0
      )
      term
    end    
  end
  
  class PostMeta < WordpressDatabase
    set_primary_key 'meta_id'
    set_table_name Wordpress::TABLE_PREFIX + 'postmeta'
    belongs_to :post, :class_name => 'Wordpress::Post', :foreign_key => 'post_id'
  end
  
  class Post < WordpressDatabase
    set_primary_key 'ID'
    set_table_name Wordpress::TABLE_PREFIX + 'posts'
        
    def self.current_user
      @@current_user ||= Wordpress::User.find(:first)
    end
    
    def self.default_term
      @@default_term ||= Wordpress::Term.find_by_name('Uncategorized')
    end
    
    def self.create_from_drupal(drupal_post)
      # Do we know about this user?
      user = Wordpress::User.find_by_user_email(drupal_post.user.mail)
      if user.nil?
        user = Wordpress::User.create_from_drupal(drupal_post.user)
      end
            
      # Create the post      
      post = create(
        :post_title => drupal_post.title,
        :post_excerpt => drupal_post.teaser,
        :post_content => drupal_post.body.gsub(/<!--\s*[Bb]reak\s*-->/,'<!--more-->'),
        :post_modified => Time.at(drupal_post.changed),
        :post_modified_gmt => Time.at(drupal_post.changed).gmtime,
        :post_date => Time.at(drupal_post.created),
        :post_date_gmt => Time.at(drupal_post.created).gmtime,
        :user => user || current_user,
        :post_name => drupal_post.to_wordpress_name,
        :guid => "http://#{Wordpress::BLOG_HOST}/#{Time.at(drupal_post.created).strftime("%Y/%m/%d")}/#{drupal_post.to_wordpress_name}"
      )
      
      # Create comments
      drupal_post.comments.each do |drupal_comment|
        post.comments.create(
          :comment_author => drupal_comment.name,
          :comment_author_email => drupal_comment.mail,
          :comment_author_url => drupal_comment.homepage,
          :comment_author_IP => drupal_comment.hostname,
          :comment_content => drupal_comment.comment,
          :comment_date => Time.at(drupal_comment.timestamp),
          :comment_date_gmt => Time.at(drupal_comment.timestamp).gmtime
        )        
      end
      
      # Assign categories
      drupal_post.terms.each {|drupal_category|
        # Do we know about this category?
        term = Wordpress::Term.find_by_name(drupal_category.name)
        if term.nil?
          term = Wordpress::Term.create_category(drupal_category.name)
        end
        term.taxonomy.increment!(:count)
        post.categories << term.taxonomy
      }
      
      # Put post without categories in the default category
      if drupal_post.terms.empty?
        term = self.default_term
        term.taxonomy.increment!(:count)
        post.categories << term.taxonomy
      end
      
      # Update comment count
      post.save
      post
    end
    
    
    belongs_to :user, :class_name => 'Wordpress::User', :foreign_key => 'post_author'

    has_and_belongs_to_many :categories, :class_name => 'Wordpress::TermTaxonomy', 
                  :join_table =>   Wordpress::TABLE_PREFIX + 'term_relationships', 
                  :foreign_key => 'object_id', 
                  :association_foreign_key => 'term_taxonomy_id'
     
    has_many :comments, :class_name => 'Wordpress::Comment', :foreign_key => 'comment_post_ID', :dependent => :destroy
    has_many :metas, :class_name => 'Wordpress::PostMeta', :foreign_key => 'post_id', :dependent => :destroy
    
    def before_save
      self.post_content = fix_url(self.post_content)
      self.post_excerpt = fix_url(self.post_excerpt)
      
      # Denormalize comments count
      self.comment_count = self.comments.size
      
      # Makes ActiveRecord happy?
      true
    end
    
    def fix_url(content)
      # 
      # Add code to fix up content, url, etc...
      # content.gsub!(/href\s*=\s*["']\/(.*?)["']/, 'href="http://www.yourdomain.com/\1"')
      content
    end
  end
    
  class Comment < WordpressDatabase
    set_primary_key 'comment_ID'
    set_table_name Wordpress::TABLE_PREFIX + 'comments'
    belongs_to :post, :class_name => 'Wordpress::Post', :foreign_key => "comment_post_ID"
  end  
end
